package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"gitee.com/haodreams/libs/easy"
	"gitee.com/haodreams/libs/intcomp"
)

func load(filePath string) (ids []int64, ivals []int64, fvals []float64, statuses []uint32, times []int64) {
	f, err := os.Open(filePath)
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()
	buf := bufio.NewReader(f)

	i := 0
	for line, err := buf.ReadString('\n'); err == nil || len(line) > 0; line, err = buf.ReadString('\n') {
		line = strings.TrimSpace(line)
		ss := strings.Split(line, ",")
		if len(ss) != 5 {
			continue
		}
		id, err := strconv.Atoi(ss[0])
		if err != nil {
			continue
		}
		i++
		// id = i //id % 1000000
		fval, err := strconv.ParseFloat(ss[4], 64)
		if err != nil {
			continue
		}
		ival := int64(0)
		if fval == 0 {
			ival = 0
			continue
		} else if fval == 1 {
			ival = 1
			continue

		} else {
			ival = int64(fval * 100)
		}

		ss[2] = strings.TrimPrefix(ss[2], "T ")
		t, err := time.Parse("2006-01-02 15:04:05", ss[2])
		if err != nil {
			continue
		}
		status, err := strconv.Atoi(ss[3])
		if err != nil {
			continue
		}
		times = append(times, t.Unix())
		statuses = append(statuses, uint32(uint16(status)))
		ids = append(ids, int64(id))
		ivals = append(ivals, ival)
		fvals = append(fvals, fval)
	}
	return
}

func main() {
	ids, ivals, fvals, statuses, times := load("test.csv")
	_ = fvals
	_ = statuses
	_ = times
	now := time.Now()
	log.Println("number:", len(ids))
	ic := intcomp.NewSeqComp[uint64](true)
	for _, id := range ids {
		ic.Write(uint64(id))
	}
	output := ic.Bytes()
	log.Printf("intcomp ids input len: %s,  output len: %s used time:%s\n", easy.BeautifySize(int64(len(ivals))*8), easy.BeautifySize(int64(len(output))), time.Since(now).String())

	now = time.Now()

	vals, err := ic.Decode(output)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("decode ids", len(vals), "used time: ", time.Since(now))

	for i, val := range vals {
		if ids[i] != int64(val) {
			log.Fatal(ids[i], int64(val))
		}
	}

	now = time.Now()
	ics := intcomp.NewSeqComp[uint32](false)
	for _, id := range fvals {
		ics.Write(uint32(id))
	}
	output = ics.Bytes()
	log.Printf("intcomp value input len: %s,  output len: %s used time:%s\n", easy.BeautifySize(int64(len(ivals))*4), easy.BeautifySize(int64(len(output))), time.Since(now).String())

	now = time.Now()

	vals2, err := ics.Decode(output)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("decode value", len(vals), "used time: ", time.Since(now))

	for i, val := range vals2 {
		if statuses[i] != uint32(val) {
			//panic(fmt.Sprintln(statuses[i], int64(val)))
		}
	}

	now = time.Now()
	ics2 := intcomp.NewIntComp(len(fvals))
	for _, id := range fvals {
		ics2.Write(int64(id * 100))
	}
	output = ics2.Flush()
	log.Printf("intcomp2 value input len: %s,  output len: %s used time:%s\n", easy.BeautifySize(int64(len(ivals))*8), easy.BeautifySize(int64(len(output))), time.Since(now).String())

	now = time.Now()

	ivals, err = ics2.Decode(output)
	if err != nil {
		log.Fatal(err)
	}
	_ = ivals
	log.Println("decode value", len(vals), "used time: ", time.Since(now))

	for i, val := range vals2 {
		if statuses[i] != uint32(val) {
			//panic(fmt.Sprintln(statuses[i], int64(val)))
		}
	}

	now = time.Now()
	ics = intcomp.NewSeqComp[uint32](false)
	for _, id := range statuses {
		ics.Write(uint32(id))
	}
	output = ics.Bytes()
	log.Printf("intcomp status input len: %s,  output len: %s used time:%s\n", easy.BeautifySize(int64(len(ivals))*4), easy.BeautifySize(int64(len(output))), time.Since(now).String())

	now = time.Now()

	vals2, err = ics.Decode(output)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("decode status", len(vals), "used time: ", time.Since(now))

	for i, val := range vals2 {
		if statuses[i] != uint32(val) {
			panic(fmt.Sprintln(statuses[i], int64(val)))
		}
	}

	now = time.Now()
	ict := intcomp.NewSeqComp[uint64](false)
	for _, id := range times {
		ict.Write(uint64(id))
	}
	output = ict.Bytes()
	log.Printf("intcomp time input len: %s,  output len: %s used time:%s\n", easy.BeautifySize(int64(len(ivals))*8), easy.BeautifySize(int64(len(output))), time.Since(now).String())

	now = time.Now()

	valst, err := ict.Decode(output)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("decode time", len(valst), "used time: ", time.Since(now))

	for i, val := range valst {
		if times[i] != int64(val) {
			panic(fmt.Sprintln(times[i], int64(val)))
		}
	}

}
